﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using SsrsRenderStudio.Shared;

namespace SsrsRenderStudio.Renderer.Support
{
    /// <summary>
    /// Paints a metafile onto a Graphics object.
    /// </summary>
    public class MetafilePainterInstance
    {
        //private System.Diagnostics.Stopwatch _debugWatch1 = new System.Diagnostics.Stopwatch();
        private System.Drawing.Imaging.Metafile _metafile = null;
        private Graphics.EnumerateMetafileProc _callback = null;

        /// <summary>
        /// Paints the Metafile on a Graphics object.
        /// </summary>
        /// <param name="metafile">Metafile to process, null will process last processed metafile.</param>
        /// <param name="destinationClip">Destination size.</param>
        /// <returns></returns>
        public void PaintImage(Graphics g, Metafile metafile, Point[] destinationClip)
        {
            //_debugWatch1.Restart();
            //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * PaintImage started, timer1 started ");
            _metafile = metafile;
            _callback  = new Graphics.EnumerateMetafileProc(MetafileCallback);
            //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * PaintImage inproc, EnumerateMetafileProc, timer3 @ " + _debugWatch1.ElapsedMilliseconds);
            g.EnumerateMetafile(_metafile, destinationClip, _callback);
            //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * PaintImage inproc, EnumerateMetafile, timer3 @ " + _debugWatch1.ElapsedMilliseconds);
            //_debugWatch1.Stop();
        }

        private bool MetafileCallback(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData)
        {
            //Logger.Log(EnumLoggingSeverity.DEBUG, recordType.ToString() + " f:" + flags.ToString() + " sz:" + dataSize.ToString());
            //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * MetafileCallback entry, timer3 @ " + _debugWatch1.ElapsedMilliseconds);
            byte[] dataArray = null;
            // Dance around unmanaged code.
            if (data != IntPtr.Zero)
            {
                // Copy the unmanaged record to a managed byte buffer that can be used by PlayRecord.
                dataArray = new byte[dataSize];
                Marshal.Copy(data, dataArray, 0, dataSize);
                //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * MetafileCallback Copy, timer3 @ " + _debugWatch1.ElapsedMilliseconds);
            }
            // play the record.      
            _metafile.PlayRecord(recordType, flags, dataSize, dataArray);
            //Logger.Log(EnumLoggingSeverity.DEBUG, "MetafilePainterInstance: * MetafileCallback PlayRecord, timer3 @ " + _debugWatch1.ElapsedMilliseconds);
            _callback = null;
            return true;
        }
    }
}
